// remotetab.cpp
#include "remotetab.h"
#include "ui_remotetab.h"
#include <QSerialPortInfo>
#include <QNetworkInterface>
#include <QTimer>

remoteTab::remoteTab(const QString &tabName, int maxRegisterAddress, QWidget *parent)
    : QWidget(parent), ui(new Ui::remoteTab), m_modbusSlave(nullptr), m_maxRegisterAddress(maxRegisterAddress)
{
    ui->setupUi(this);

    // 设置远程名称输入框的初始值
    if (!tabName.isEmpty())
    {
        ui->le_remoteName->setText(tabName);
    }

    // 初始化连接类型下拉列表
    ui->cb_connectType->clear();
    ui->cb_connectType->addItem(QStringLiteral("485传输"));
    // ui->cb_connectType->addItem(QStringLiteral("网络客户端传输"));
    ui->cb_connectType->addItem(QStringLiteral("网络服务端监听"));

    // 初始化串口列表
    initSerialPorts();

    // 初始化波特率列表
    initBaudRates();

    // 初始化网卡设备列表
    initNetworkDevices();

    // 初始化端口号输入框
    ui->le_port->setValidator(new QIntValidator(1, 65535, this));

    // 连接网卡选择变化信号
    connect(ui->cb_connectType_4, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &remoteTab::on_cb_connectType_4_currentIndexChanged);
    ui->label_10->setVisible(false);
    ui->le_localIp->setVisible(false);

    // 创建并启动串口刷新定时器
    m_serialPortRefreshTimer = new QTimer(this);
    connect(m_serialPortRefreshTimer, &QTimer::timeout, this, &remoteTab::initSerialPorts);
    m_serialPortRefreshTimer->start(3000); // 每1000毫秒(1秒)刷新一次
}

remoteTab::~remoteTab()
{
    if (m_modbusSlave)
    {
        m_modbusSlave->stop();
        delete m_modbusSlave;
    }
    // 定时器会自动被父对象删除
    delete ui;
}

void remoteTab::initSerialPorts()
{
    // // 如果用户正在下拉列表中操作，暂时不刷新
    // if (ui->cb_connectType_2->view() && ui->cb_connectType_2->view()->isVisible())
    // {
    //     return;
    // }

    // 保存当前选择的串口名称
    QString currentPort;
    if (ui->cb_connectType_2->currentIndex() >= 0 && ui->cb_connectType_2->currentIndex() < ui->cb_connectType_2->count())
    {
        currentPort = ui->cb_connectType_2->currentText();
    }

    // 清空并重新填充串口列表
    ui->cb_connectType_2->clear();
    QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &port : ports)
    {
        ui->cb_connectType_2->addItem(port.portName());
    }

    // 如果之前有选择且当前列表中存在，则恢复选择
    if (!currentPort.isEmpty())
    {
        int index = ui->cb_connectType_2->findText(currentPort);
        if (index >= 0)
        {
            ui->cb_connectType_2->setCurrentIndex(index);
        }
        else if (ui->cb_connectType_2->count() > 0)
        {
            ui->cb_connectType_2->setCurrentIndex(0);
        }
    }
    else if (ui->cb_connectType_2->count() > 0)
    {
        ui->cb_connectType_2->setCurrentIndex(0);
    }
}

void remoteTab::initBaudRates()
{
    // 常用波特率列表
    QStringList baudRates;
    baudRates << "9600" << "19200" << "38400" << "57600" << "115200";

    // 保存当前选择的波特率
    QString currentBaudRate;
    if (ui->cb_connectType_3->currentIndex() >= 0 && ui->cb_connectType_3->currentIndex() < ui->cb_connectType_3->count())
    {
        currentBaudRate = ui->cb_connectType_3->currentText();
    }

    // 清空并重新填充波特率列表
    ui->cb_connectType_3->clear();
    for (const QString &baudRate : baudRates)
    {
        ui->cb_connectType_3->addItem(baudRate);
    }

    // 如果之前有选择且当前列表中存在，则恢复选择
    if (!currentBaudRate.isEmpty())
    {
        int index = ui->cb_connectType_3->findText(currentBaudRate);
        if (index >= 0)
        {
            ui->cb_connectType_3->setCurrentIndex(index);
        }
        else if (ui->cb_connectType_3->count() > 0)
        {
            ui->cb_connectType_3->setCurrentIndex(0);
        }
    }
    else if (ui->cb_connectType_3->count() > 0)
    {
        ui->cb_connectType_3->setCurrentIndex(0);
    }
}

void remoteTab::initNetworkDevices()
{
    // 清空网卡设备列表，实际列表将通过setNetworkDevices设置
    ui->cb_connectType_4->clear();
}

void remoteTab::on_le_remoteName_textEdited(const QString &arg1)
{
    emit tabNameChanged(arg1);
}

void remoteTab::on_cb_connectType_currentIndexChanged(int index)
{
    ui->stackedWidget->setCurrentIndex(index);
}

void remoteTab::on_cb_connectType_4_currentIndexChanged(int index)
{
    // 网卡选择变化时发出信号
    if (index >= 0 && index < ui->cb_connectType_4->count())
    {
        QString deviceName = ui->cb_connectType_4->currentText();
        // emit networkDeviceChanged(deviceName);

        // 获取网卡的真实IP地址而不是配置中的IP地址
        QString realIpAddress = getRealIpAddress(deviceName);
        if (!realIpAddress.isEmpty())
        {
            ui->le_localIp->setText(realIpAddress);
        }
        else
        {
            // 如果获取不到真实IP，再尝试从配置中读取
            if (m_networkConfigs.contains(deviceName))
            {
                QJsonObject deviceConfig = m_networkConfigs[deviceName];
                QString localIp = deviceConfig["local_ip"].toString();
                ui->le_localIp->setText(localIp);
            }
        }
    }
}

QJsonObject remoteTab::getParameters() const
{
    QJsonObject params;

    // 收集所有参数
    params["remoteName"] = ui->le_remoteName->text();
    params["localId"] = ui->spinBox->value();
    params["connectType"] = ui->cb_connectType->currentIndex();

    // 添加端口号参数
    params["port"] = ui->le_port->text().toInt();

    // UART参数
    if (ui->cb_connectType_2->count() > 0)
    {
        params["uartPort"] = ui->cb_connectType_2->currentIndex();
    }
    if (ui->cb_connectType_3->count() > 0)
    {
        params["baudRate"] = ui->cb_connectType_3->currentIndex();
    }

    // 网络设备选择
    if (ui->cb_connectType_4->count() > 0)
    {
        QString selectedDevice = ui->cb_connectType_4->currentText();
        params["selectedNetworkDevice"] = selectedDevice;

        // 添加选定网卡的IP地址（使用真实IP）
        QString realIpAddress = getRealIpAddress(selectedDevice);
        if (!realIpAddress.isEmpty())
        {
            params["selectedNetworkIP"] = realIpAddress;
        }
        else if (m_networkConfigs.contains(selectedDevice))
        {
            QJsonObject deviceConfig = m_networkConfigs[selectedDevice];
            params["selectedNetworkIP"] = deviceConfig["local_ip"].toString();
        }
    }

    return params;
}

void remoteTab::setNetworkConfigs(const QMap<QString, QJsonObject> &configs)
{
    m_networkConfigs = configs;
}

void remoteTab::setParameters(const QJsonObject &params)
{
    // 设置参数值
    if (params.contains("remoteName"))
        ui->le_remoteName->setText(params["remoteName"].toString());

    if (params.contains("localId"))
        ui->spinBox->setValue(params["localId"].toInt());

    if (params.contains("connectType"))
        ui->cb_connectType->setCurrentIndex(params["connectType"].toInt());

    // 设置端口号
    if (params.contains("port"))
    {
        ui->le_port->setText(QString::number(params["port"].toInt()));
    }

    // UART参数
    if (params.contains("uartPort"))
    {
        int uartPortIndex = params["uartPort"].toInt();
        if (uartPortIndex >= 0 && uartPortIndex < ui->cb_connectType_2->count())
        {
            ui->cb_connectType_2->setCurrentIndex(uartPortIndex);
        }
    }

    if (params.contains("baudRate"))
    {
        int baudRateIndex = params["baudRate"].toInt();
        if (baudRateIndex >= 0 && baudRateIndex < ui->cb_connectType_3->count())
        {
            ui->cb_connectType_3->setCurrentIndex(baudRateIndex);
        }
    }

    // 网络设备选择
    if (params.contains("selectedNetworkDevice"))
    {
        QString selectedDevice = params["selectedNetworkDevice"].toString();
        int deviceIndex = ui->cb_connectType_4->findText(selectedDevice);
        if (deviceIndex >= 0)
        {
            ui->cb_connectType_4->setCurrentIndex(deviceIndex);
        }
    }

    // 更新本地IP显示
    if (params.contains("selectedNetworkDevice"))
    {
        QString selectedDevice = params["selectedNetworkDevice"].toString();
        QString realIpAddress = getRealIpAddress(selectedDevice);
        if (!realIpAddress.isEmpty())
        {
            ui->le_localIp->setText(realIpAddress);
        }
        else if (params.contains("selectedNetworkIP"))
        {
            ui->le_localIp->setText(params["selectedNetworkIP"].toString());
        }
    }
    else if (params.contains("selectedNetworkIP"))
    {
        ui->le_localIp->setText(params["selectedNetworkIP"].toString());
    }

    // 根据参数设置Modbus从站
    setupModbusSlave(params);
}

void remoteTab::setNetworkDevices(const QStringList &devices)
{
    // 保存当前选择的网卡设备
    QString currentDevice;
    if (ui->cb_connectType_4->currentIndex() >= 0 && ui->cb_connectType_4->currentIndex() < ui->cb_connectType_4->count())
    {
        currentDevice = ui->cb_connectType_4->currentText();
    }

    // 清空并重新填充网卡设备列表
    ui->cb_connectType_4->clear();
    for (const QString &device : devices)
    {
        ui->cb_connectType_4->addItem(device);
    }

    // 如果之前有选择且当前列表中存在，则恢复选择
    if (!currentDevice.isEmpty())
    {
        int index = ui->cb_connectType_4->findText(currentDevice);
        if (index >= 0)
        {
            ui->cb_connectType_4->setCurrentIndex(index);
        }
        else if (ui->cb_connectType_4->count() > 0)
        {
            ui->cb_connectType_4->setCurrentIndex(0);
        }
    }
    else if (ui->cb_connectType_4->count() > 0)
    {
        ui->cb_connectType_4->setCurrentIndex(0);
    }
}

void remoteTab::updateModbusDataMap(const QMap<QString, QString> &dataMap)
{
    // 使用常量引用传递，避免不必要的拷贝
    m_modbusDataMap = dataMap;

    // 如果Modbus从站存在，更新其数据映射
    if (m_modbusSlave)
    {
        // 将QString映射转换为int映射（假设modbus地址是数字）
        QMap<int, QVariant> intDataMap;
        for (auto it = dataMap.begin(); it != dataMap.end(); ++it)
        {
            bool ok;
            int address = it.key().toInt(&ok);
            if (ok)
            {
                intDataMap[address] = it.value();
            }
        }
        m_modbusSlave->setDataMap(intDataMap);
    }
}

void remoteTab::setupModbusSlave(const QJsonObject &params)
{
    qDebug() << "=== setupModbusSlave called ===";
    qDebug() << "Parameters:" << params;

    // 停止并删除现有的Modbus从站实例
    if (m_modbusSlave)
    {
        m_modbusSlave->stop();
        delete m_modbusSlave;
        m_modbusSlave = nullptr;
    }

    // 检查连接类型，1表示网络客户端传输(TCP)
    int connectType = params["connectType"].toInt(0);
    qDebug() << "Connection type:" << connectType << (connectType == 1 ? "(TCP)" : "(RTU)");

    // 获取从机地址
    int slaveId = params["localId"].toInt(1); // 默认从机地址为1
    qDebug() << "Slave ID:" << slaveId;

    qDebug() << "Max register address:" << m_maxRegisterAddress;

    if (connectType == 1)
    { // TCP服务器传输
        int port = params["port"].toInt(502);
        QString networkDevice = params["selectedNetworkDevice"].toString();

        qDebug() << "Creating TCP server on port:" << port;

        // 创建TCP类型的Modbus从站(服务器)，传入最大寄存器地址
        m_modbusSlave = new modbusSlave(modbusSlave::TCP, m_maxRegisterAddress, this);
        // 从网络配置中获取对应设备的IP地址
        QString ipAddress = "0.0.0.0"; // 默认监听所有接口

        // 优先使用真实IP地址
        QString realIpAddress = getRealIpAddress(networkDevice);
        if (!realIpAddress.isEmpty())
        {
            ipAddress = realIpAddress;
        }
        else if (m_networkConfigs.contains(networkDevice))
        {
            QJsonObject deviceConfig = m_networkConfigs[networkDevice];
            ipAddress = deviceConfig["local_ip"].toString();
        }

        qDebug() << "IP Address:" << ipAddress;

        m_modbusSlave->setTCPConnectionParameters(ipAddress, port);
        m_modbusSlave->setSlaveId(slaveId); // 设置从机地址

        // 启动Modbus从站
        qDebug() << "Starting Modbus TCP slave with ID:" << slaveId << "on" << ipAddress << ":" << port;
        if (!m_modbusSlave->start())
        {
            qDebug() << "Failed to start Modbus TCP slave";
        }
        else
        {
            qDebug() << "Modbus TCP slave started successfully";
        }
    }
    else if (connectType == 0)
    { // 485传输(RTU)
        // 获取串口参数
        int uartPortIndex = params["uartPort"].toInt(0);
        int baudRateIndex = params["baudRate"].toInt(0);

        // 获取串口名称
        QString portName;
        if (ui->cb_connectType_2->count() > uartPortIndex)
        {
            portName = ui->cb_connectType_2->itemText(uartPortIndex);
        }

        // 获取波特率
        QStringList baudRates;
        baudRates << "9600" << "19200" << "38400" << "57600" << "115200";
        int baudRate = 9600;
        if (baudRateIndex >= 0 && baudRateIndex < baudRates.size())
        {
            baudRate = baudRates[baudRateIndex].toInt();
        }

        if (!portName.isEmpty())
        {
            // 创建RTU类型的Modbus从站，传入最大寄存器地址
            m_modbusSlave = new modbusSlave(modbusSlave::RTU, m_maxRegisterAddress, this);
            m_modbusSlave->setRTUConnectionParameters(portName, baudRate, "None");
            m_modbusSlave->setSlaveId(slaveId); // 设置从机地址

            // 启动Modbus从站
            qDebug() << "Starting Modbus RTU slave with ID:" << slaveId << "on port:" << portName;
            if (!m_modbusSlave->start())
            {
                qDebug() << "Failed to start Modbus RTU slave";
            }
            else
            {
                qDebug() << "Modbus RTU slave started successfully";
            }
        }
    }

    // 如果有现有的数据映射，设置给新的Modbus从站
    if (m_modbusSlave && !m_modbusDataMap.isEmpty())
    {
        qDebug() << "Setting data map with" << m_modbusDataMap.size() << "items";
        QMap<int, QVariant> intDataMap;
        for (auto it = m_modbusDataMap.begin(); it != m_modbusDataMap.end(); ++it)
        {
            bool ok;
            int address = it.key().toInt(&ok);
            if (ok)
            {
                intDataMap[address] = it.value();
            }
        }
        m_modbusSlave->setDataMap(intDataMap);
    }

    qDebug() << "=== setupModbusSlave completed ===";
}

QString remoteTab::getRealIpAddress(const QString &deviceName) const
{
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    for (const QNetworkInterface &interface : interfaces)
    {
        if (interface.name() == deviceName)
        {
            QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
            for (const QNetworkAddressEntry &entry : addressEntries)
            {
                // 我们通常关心IPv4地址
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
                {
                    return entry.ip().toString();
                }
            }
            break;
        }
    }
    return QString(); // 返回空字符串表示未找到
}
